From 784905204897c004a990a25aed49dcccb6e2da54 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 15 Mar 2004 17:56:41 +0000 Subject: [PATCH] bitkeeper revision 1.800 (4055ee59_zI1OKOsC2EKXBIYFm3OtA) console_client.py, __init__.py, setup.py, Makefile: new file Many files: New console-terminal client in xenctl.console_client Python package. New option to xc_dom_create (-c on cmdline or auto_console in defaults file) to automatically become a console client. utils.py: Rename: tools/xc/py/XenoUtil.py -> tools/xenctl/lib/utils.py --- .rootkeys | 6 +- README.CD | 5 -- docs/VBD-HOWTO.txt | 2 +- docs/Xeno-HOWTO.txt | 6 +- tools/Makefile | 3 + tools/examples/README | 2 +- tools/examples/defaults | 8 +-- tools/examples/democd | 10 ++-- tools/examples/netbsd | 10 ++-- tools/examples/xc_dom_control.py | 18 +++--- tools/examples/xc_dom_create.py | 23 ++++--- tools/examples/xc_vd_tool.py | 22 +++---- tools/xc/py/setup.py | 2 - tools/xenctl/Makefile | 10 ++++ tools/xenctl/lib/__init__.py | 0 tools/xenctl/lib/console_client.py | 60 +++++++++++++++++++ .../py/XenoUtil.py => xenctl/lib/utils.py} | 4 +- tools/xenctl/setup.py | 8 +++ 18 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 tools/xenctl/Makefile create mode 100644 tools/xenctl/lib/__init__.py create mode 100644 tools/xenctl/lib/console_client.py rename tools/{xc/py/XenoUtil.py => xenctl/lib/utils.py} (99%) create mode 100644 tools/xenctl/setup.py diff --git a/.rootkeys b/.rootkeys index 55b2575247..c21b6eebe4 100644 --- a/.rootkeys +++ b/.rootkeys @@ -86,8 +86,12 @@ 3fbba6dc38q-ioRlwSR_quw4G3qUeQ tools/xc/lib/xc_vif.c 3fbd0a3dTwnDcfdw0-v46dPbX98zDw tools/xc/py/Makefile 3fbd0a42l40lM0IICw2jXbQBVZSdZg tools/xc/py/Xc.c -3fbd4bd6GtGwZGxYUJPOheYIR7bPaA tools/xc/py/XenoUtil.py 3fbd0a40yT6G3M9hMpaz5xTUdl0E4g tools/xc/py/setup.py +4055ee41IfFazrwadCH2J72nz-A9YA tools/xenctl/Makefile +4055ee4b_4Rvns_KzE12csI14EKK6Q tools/xenctl/lib/__init__.py +4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/xenctl/lib/console_client.py +3fbd4bd6GtGwZGxYUJPOheYIR7bPaA tools/xenctl/lib/utils.py +4055ee44Bu6oP7U0WxxXypbUt4dNPQ tools/xenctl/setup.py 40431ac64Hj4ixUnKmlugZKhXPFE_Q tools/xend/Makefile 4055ad95Se-FqttgxollqOAAHB94zA tools/xend/lib/__init__.py 4055ad97wMLUj0BZT0e_T0EwQN0Bvw tools/xend/lib/console.py diff --git a/README.CD b/README.CD index e9d172f268..2beb6fb150 100644 --- a/README.CD +++ b/README.CD @@ -464,11 +464,6 @@ You can rebuild Xen and the tools by typing 'make'. You can install them to the standard directories with 'make install', or into the ../install subtree with 'make dist'. -/usr/local/bin/xc_* the domain control tools -/lib/libxc.so the xc library -/usr/lib/python2.2/site-packages/XenoUtil.py python util library -/usr/lib/python2.2/site-packages/Xc.c python xc bindings - If you're using the virtual disk control tools (xc_vd_tool) you'll need the SQLite library and python binding pysqlite. There's a tar ball containing the necessary binaries on the project downloads page. diff --git a/docs/VBD-HOWTO.txt b/docs/VBD-HOWTO.txt index 870ea2e040..b6feb104c2 100644 --- a/docs/VBD-HOWTO.txt +++ b/docs/VBD-HOWTO.txt @@ -152,7 +152,7 @@ freespace - Get the free space (in megabytes) available for allocating new virtual disk extents. The functionality provided by these scripts is also available directly from -Python functions in the XenoUtil module - you can use this functionality in +Python functions in the xenctl.utils module - you can use this functionality in your own scripts. Populating VDs: diff --git a/docs/Xeno-HOWTO.txt b/docs/Xeno-HOWTO.txt index 167615d758..a2b1906f71 100644 --- a/docs/Xeno-HOWTO.txt +++ b/docs/Xeno-HOWTO.txt @@ -312,10 +312,10 @@ provide access to privileged command operations: In this way you can see that the class 'xc' contains useful documentation for you to consult. -A further module of useful routines (XenoUtil) is also installed: +A further package of useful routines (xenctl) is also installed: -# import XenoUtil -# help(XenoUtil) +# import xenctl.utils +# help(xenctl.utils) You can use these modules to write your own custom scripts or you can customise the scripts supplied in the Xen distribution. diff --git a/tools/Makefile b/tools/Makefile index 720b61417f..3bc0d81eaf 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,6 +23,7 @@ all: $(MAKE) -C misc $(MAKE) -C examples $(MAKE) -C xentrace + $(MAKE) -C xenctl $(MAKE) -C xend install: all @@ -31,6 +32,7 @@ install: all $(MAKE) -C misc install $(MAKE) -C examples install $(MAKE) -C xentrace install + $(MAKE) -C xenctl install $(MAKE) -C xend install clean: @@ -40,5 +42,6 @@ clean: $(MAKE) -C examples clean $(MAKE) -C nsplitd clean $(MAKE) -C xentrace clean + $(MAKE) -C xenctl clean $(MAKE) -C xend clean diff --git a/tools/examples/README b/tools/examples/README index 82041d7ad1..565b5c5c76 100644 --- a/tools/examples/README +++ b/tools/examples/README @@ -5,7 +5,7 @@ This directory contains a set of example scripts for common Xen operations. For many operations you will either be able to use these scripts directly, or incorporate code from them into your own scripts. -The Xc and XenoUtil Python modules provide an API for accessing all this +The Xc and xenctl.utils Python modules provide an API for accessing all this functionality - and more - from your own Python programs. These libraries may contain features for which there aren't yet example scripts written for... diff --git a/tools/examples/defaults b/tools/examples/defaults index 8852094eea..9f1a7874ab 100644 --- a/tools/examples/defaults +++ b/tools/examples/defaults @@ -42,8 +42,8 @@ domain_name = "This is VM %d" % vmid # appropriately. #vfr_ipaddr = ["111.222.333.444","222.333.444.555"] -vfr_ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),vmid), - XenoUtil.add_offset_to_ip('169.254.1.0',vmid),] +vfr_ipaddr = [xenctl.utils.add_offset_to_ip(xenctl.utils.get_current_ipaddr(),vmid), + xenctl.utils.add_offset_to_ip('169.254.1.0',vmid),] # STEP 5a. Identify any physcial partitions or virtual disks you want the @@ -72,8 +72,8 @@ vbd_expert = 0 # You can use 'extrabit' to set the runlevel and custom environment # variables used by custom rc scripts (e.g. VMID=, usr= ) -netmask = XenoUtil.get_current_ipmask() -gateway = XenoUtil.get_current_ipgw() +netmask = xenctl.utils.get_current_ipmask() +gateway = xenctl.utils.get_current_ipgw() nfsserv = '169.254.1.0' cmdline_ip = "ip="+vfr_ipaddr[0]+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off" diff --git a/tools/examples/democd b/tools/examples/democd index 4d6e90033f..b8e9c0c928 100644 --- a/tools/examples/democd +++ b/tools/examples/democd @@ -49,7 +49,7 @@ else: # appropriately. #vfr_ipaddr = ["111.222.333.444","222.333.444.555"] -#vfr_ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),vmid)] +#vfr_ipaddr = [xenctl.utils.add_offset_to_ip(xenctl.utils.get_current_ipaddr(),vmid)] vfr_ipaddr = map(socket.gethostbyname,string.split(ip,',')) @@ -83,7 +83,7 @@ vbd_expert = 0 # see if we have a local IP at all localip='' for i in vfr_ipaddr: - if XenoUtil.check_subnet(i,'169.254.0.0','255.255.0.0'): + if xenctl.utils.check_subnet(i,'169.254.0.0','255.255.0.0'): localip=i break @@ -99,15 +99,15 @@ try: myip = vfr_ipaddr[0] except NameError: - netmask = XenoUtil.get_current_ipmask() - gateway = XenoUtil.get_current_ipgw() + netmask = xenctl.utils.get_current_ipmask() + gateway = xenctl.utils.get_current_ipgw() # if we haven't got an address, see if we have one that matches the LAN if not myip: if netmask and gateway: for i in vfr_ipaddr: - if XenoUtil.check_subnet(i,gateway,netmask): + if xenctl.utils.check_subnet(i,gateway,netmask): myip=i break diff --git a/tools/examples/netbsd b/tools/examples/netbsd index 6050c8bc23..f3dcccbea3 100644 --- a/tools/examples/netbsd +++ b/tools/examples/netbsd @@ -57,10 +57,10 @@ except: #vfr_ipaddr = ["111.222.333.444","222.333.444.555"] try: - vfr_ipaddr = [ip, XenoUtil.add_offset_to_ip('169.254.1.0',vmid),] + vfr_ipaddr = [ip, xenctl.utils.add_offset_to_ip('169.254.1.0',vmid),] except: - vfr_ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),vmid), - XenoUtil.add_offset_to_ip('169.254.1.0',vmid),] + vfr_ipaddr = [xenctl.utils.add_offset_to_ip(xenctl.utils.get_current_ipaddr(),vmid), + xenctl.utils.add_offset_to_ip('169.254.1.0',vmid),] # STEP 5a. Identify any physcial partitions or virtual disks you want the @@ -89,8 +89,8 @@ vbd_expert = 0 # You can use 'extrabit' to set the runlevel and custom environment # variables used by custom rc scripts (e.g. VMID=, usr= ) -netmask = XenoUtil.get_current_ipmask() -gateway = XenoUtil.get_current_ipgw() +netmask = xenctl.utils.get_current_ipmask() +gateway = xenctl.utils.get_current_ipgw() try: nfsserv except: diff --git a/tools/examples/xc_dom_control.py b/tools/examples/xc_dom_control.py index 638a509106..0ca2c97ac2 100755 --- a/tools/examples/xc_dom_control.py +++ b/tools/examples/xc_dom_control.py @@ -184,8 +184,8 @@ elif cmd == 'vif_addip': ip = sys.argv[4] # XXX This function should be moved to Xc once we sort out the VFR - import XenoUtil - XenoUtil.setup_vfr_rules_for_vif( dom, vif, ip ) + import xenctl.utils + xenctl.utils.setup_vfr_rules_for_vif( dom, vif, ip ) elif cmd == 'vif_setsched': if len(sys.argv) < 6: @@ -211,9 +211,9 @@ elif cmd == 'vif_getsched': elif cmd == 'vbd_add': - import XenoUtil + import xenctl.utils - XenoUtil.VBD_EXPERT_LEVEL = 0 # sets the allowed level of potentially unsafe mappings + xenctl.utils.VBD_EXPERT_LEVEL = 0 # sets the allowed level of potentially unsafe mappings if len(sys.argv) < 6: usage() @@ -227,17 +227,17 @@ elif cmd == 'vbd_add': if mode == 'rw' or mode == 'w': writeable = 1; - segments = XenoUtil.lookup_disk_uname(uname) + segments = xenctl.utils.lookup_disk_uname(uname) if not segments: print "Lookup Failed" sys.exit(1) - if XenoUtil.vd_extents_validate(segments,writeable) < 0: + if xenctl.utils.vd_extents_validate(segments,writeable) < 0: print "That mapping is too unsafe for the current VBD expertise level" sys.exit(1) - virt_dev = XenoUtil.blkdev_name_to_number(dev) + virt_dev = xenctl.utils.blkdev_name_to_number(dev) xc.vbd_create(dom,virt_dev,writeable) @@ -248,14 +248,14 @@ elif cmd == 'vbd_add': print "Added disk/partition %s to domain %d as device %s (%x)" % (uname, dom, dev, virt_dev) elif cmd == 'vbd_remove': - import XenoUtil + import xenctl.utils if len(sys.argv) < 4: usage() sys.exit(1) dev = sys.argv[3] - virt_dev = XenoUtil.blkdev_name_to_number(dev) + virt_dev = xenctl.utils.blkdev_name_to_number(dev) if not xc.vbd_destroy(dom,virt_dev): print "Removed disk/partition attached as device %s (%x) in domain %d" % (dev, virt_dev, dom) diff --git a/tools/examples/xc_dom_create.py b/tools/examples/xc_dom_create.py index 94f37a4494..886dd31f0f 100755 --- a/tools/examples/xc_dom_create.py +++ b/tools/examples/xc_dom_create.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -import Xc, XenoUtil, string, sys, os, time, socket, getopt, signal, syslog +import string, sys, os, time, socket, getopt, signal, syslog +import Xc, xenctl.utils, xenctl.console_client config_dir = '/etc/xc/' config_file = xc_config_file = config_dir + 'defaults' @@ -29,6 +30,7 @@ Arguments to control the parsing of the defaults file: def extra_usage (): print >>sys.stderr,""" Arguments to override current config read from '%s': + -c -- Turn into console terminal after domain is created -k image -- Path to kernel image ['%s'] -r ramdisk -- Path to ramdisk (or empty) ['%s'] -b builder_fn -- Function to use to build domain ['%s'] @@ -86,12 +88,13 @@ mem_size=0; domain_name=''; vfr_ipaddr=[]; vbd_expert=0; auto_restart=False; vbd_list = []; cmdline_ip = ''; cmdline_root=''; cmdline_extra='' pci_device_list = [] +auto_console = False ##### Determine location of defautls file ##### try: - opts, args = getopt.getopt(sys.argv[1:], "h?nqf:D:k:r:b:m:N:a:e:d:i:I:R:E:L:" ) + opts, args = getopt.getopt(sys.argv[1:], "h?nqcf:D:k:r:b:m:N:a:e:d:i:I:R:E:L:" ) for opt in opts: if opt[0] == '-f': config_file= opt[1] @@ -160,6 +163,7 @@ for opt in opts: if opt[0] == '-R': cmdline_root = opt[1] if opt[0] == '-E': cmdline_extra = opt[1] if opt[0] == '-i': x_vfr_ipaddr.append(opt[1]) + if opt[0] == '-c': auto_console = True if opt[0] == '-d': try: vv = string.split(opt[1],';') @@ -238,7 +242,7 @@ def make_domain(): sys.exit() cmsg = 'new_control_interface(dom='+str(id)+')' - xend_response = XenoUtil.xend_control_message(cmsg) + xend_response = xenctl.utils.xend_control_message(cmsg) if not xend_response['success']: print "Error creating initial event channel" print "Error type: " + xend_response['error_type'] @@ -251,12 +255,12 @@ def make_domain(): # setup the virtual block devices # set the expertise level appropriately - XenoUtil.VBD_EXPERT_MODE = vbd_expert + xenctl.utils.VBD_EXPERT_MODE = vbd_expert for ( uname, virt_name, rw ) in vbd_list: - virt_dev = XenoUtil.blkdev_name_to_number( virt_name ) + virt_dev = xenctl.utils.blkdev_name_to_number( virt_name ) - segments = XenoUtil.lookup_disk_uname( uname ) + segments = xenctl.utils.lookup_disk_uname( uname ) if not segments: print "Error looking up %s\n" % uname xc.domain_destroy ( dom=id ) @@ -264,7 +268,7 @@ def make_domain(): # check that setting up this VBD won't violate the sharing # allowed by the current VBD expertise level - if XenoUtil.vd_extents_validate(segments, rw=='w' or rw=='rw') < 0: + if xenctl.utils.vd_extents_validate(segments, rw=='w' or rw=='rw') < 0: xc.domain_destroy( dom = id ) sys.exit() @@ -282,7 +286,7 @@ def make_domain(): # setup virtual firewall rules for all aliases for ip in vfr_ipaddr: - XenoUtil.setup_vfr_rules_for_vif( id, 0, ip ) + xenctl.utils.setup_vfr_rules_for_vif( id, 0, ip ) # check for physical device access for (pci_bus, pci_dev, pci_func) in pci_device_list: @@ -328,6 +332,9 @@ def death_handler(dummy1,dummy2): (current_id, current_port) = make_domain() output("VM started in domain %d. Console I/O available on TCP port %d." % (current_id,current_port)) +if auto_console: + xenctl.console_client.connect('127.0.0.1',int(current_port)) + # if the auto_restart flag is set then keep polling to see if the domain is # alive - restart if it is not by calling make_domain() again (it's necessary # to update the id variable, since the new domain may have a new ID) diff --git a/tools/examples/xc_vd_tool.py b/tools/examples/xc_vd_tool.py index 95e316c741..9184d357bd 100755 --- a/tools/examples/xc_vd_tool.py +++ b/tools/examples/xc_vd_tool.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import XenoUtil, sys, re, string +import xenctl.utils, sys, re, string def usage(): @@ -50,7 +50,7 @@ if cmd == 'initialise': print "Device: " + dev print "Extent size: " + str(extent_size) + "MB" - rc = XenoUtil.vd_format(dev, extent_size) + rc = xenctl.utils.vd_format(dev, extent_size) elif cmd == 'create': @@ -63,7 +63,7 @@ elif cmd == 'create': print "Size: %d" % size print "Expiry time (seconds from now): %d" % expiry_time - src = XenoUtil.vd_create(size, expiry_time) + src = xenctl.utils.vd_create(size, expiry_time) elif cmd == 'enlarge': @@ -71,7 +71,7 @@ elif cmd == 'enlarge': extra_size = int(sys.argv[3]) - rc = XenoUtil.vd_enlarge(id, extra_size) + rc = xenctl.utils.vd_enlarge(id, extra_size) elif cmd == 'delete': @@ -79,7 +79,7 @@ elif cmd == 'delete': print "Deleting a virtual disk with ID: " + id - rc = XenoUtil.vd_delete(id) + rc = xenctl.utils.vd_delete(id) elif cmd == 'import': @@ -90,7 +90,7 @@ elif cmd == 'import': print "Allocate new virtual disk and populate from file : %s" % file - print XenoUtil.vd_read_from_file(file, expiry_time) + print xenctl.utils.vd_read_from_file(file, expiry_time) elif cmd == 'export': @@ -99,7 +99,7 @@ elif cmd == 'export': print "Dump contents of virtual disk to file : %s" % file - rc = XenoUtil.vd_cp_to_file(id, file ) + rc = xenctl.utils.vd_cp_to_file(id, file ) elif cmd == 'setexpiry': @@ -112,19 +112,19 @@ elif cmd == 'setexpiry': print "Id: " + id print "Expiry time (seconds from now [or 0]): " + str(expiry_time) - rc = XenoUtil.vd_refresh(id, expiry_time) + rc = xenctl.utils.vd_refresh(id, expiry_time) elif cmd == 'list': print 'ID Size(MB) Expiry' - for vbd in XenoUtil.vd_list(): + for vbd in xenctl.utils.vd_list(): vbd['size_mb'] = vbd['size'] / 2048 vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never' print '%(vdisk_id)-4s %(size_mb)-12d %(expiry)s' % vbd elif cmd == 'freespace': - print XenoUtil.vd_freespace() + print xenctl.utils.vd_freespace() elif cmd == 'undelete': @@ -133,7 +133,7 @@ elif cmd == 'undelete': if len(sys.argv) > 3: expiry_time = int(sys.argv[3]) - if XenoUtil.vd_undelete(id, expiry_time): + if xenctl.utils.vd_undelete(id, expiry_time): print "Undelete operation failed for virtual disk: " + id else: print "Undelete operation succeeded for virtual disk: " + id diff --git a/tools/xc/py/setup.py b/tools/xc/py/setup.py index 6d8f4f83f0..a49971ab9f 100644 --- a/tools/xc/py/setup.py +++ b/tools/xc/py/setup.py @@ -8,5 +8,3 @@ module = Extension("Xc", sources = ["Xc.c"]) setup(name = "Xc", version = "1.0", ext_modules = [module]) - -setup(name = "XenoUtil", version = "1.0", py_modules = ["XenoUtil"]) diff --git a/tools/xenctl/Makefile b/tools/xenctl/Makefile new file mode 100644 index 0000000000..e3583f5dd8 --- /dev/null +++ b/tools/xenctl/Makefile @@ -0,0 +1,10 @@ + +all: + python setup.py build + +install: all + if [ "$(prefix)" = "" ]; then python setup.py install; \ + else python setup.py install --home="$(prefix)"; fi + +clean: + rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/xenctl/lib/__init__.py b/tools/xenctl/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/xenctl/lib/console_client.py b/tools/xenctl/lib/console_client.py new file mode 100644 index 0000000000..74fc978bf2 --- /dev/null +++ b/tools/xenctl/lib/console_client.py @@ -0,0 +1,60 @@ + +############################################## +# Console client for Xen guest OSes +# Copyright (c) 2004, K A Fraser +############################################## + +import errno, os, signal, socket, struct, sys, termios + +def __child_death(signum, frame): + global stop + stop = True + +def __recv_from_sock(sock): + global stop + stop = False + print "************ REMOTE CONSOLE: CTRL-] TO QUIT ********" + while not stop: + try: + data = sock.recv(1) + os.write(1, data) + except socket.error, error: + if error[0] != errno.EINTR: + raise + print + print "************ REMOTE CONSOLE EXITED *****************" + os.wait() + +def __send_to_sock(sock): + while 1: + data = os.read(0,1) + if ord(data[0]) == ord(']')-64: + break + sock.send(data) + sys.exit(0) + +def connect(host,port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, + struct.pack('ii', 0, 0)) + sock.connect((host,port)) + + oattrs = termios.tcgetattr(0) + nattrs = termios.tcgetattr(0) + nattrs[3] = nattrs[3] & ~(termios.ECHO | termios.ICANON) + nattrs[6][termios.VMIN] = 1 + nattrs[6][termios.VTIME] = 0 + termios.tcsetattr(0, termios.TCSAFLUSH, nattrs) + + try: + if os.fork(): + signal.signal(signal.SIGCHLD, __child_death) + __recv_from_sock(sock) + else: + __send_to_sock(sock) + finally: + termios.tcsetattr(0, termios.TCSAFLUSH, oattrs) + +if __name__ == '__main__': + main(str(sys.argv[1]),int(sys.argv[2])) diff --git a/tools/xc/py/XenoUtil.py b/tools/xenctl/lib/utils.py similarity index 99% rename from tools/xc/py/XenoUtil.py rename to tools/xenctl/lib/utils.py index 520f585062..3f0914f73f 100644 --- a/tools/xc/py/XenoUtil.py +++ b/tools/xenctl/lib/utils.py @@ -448,9 +448,9 @@ def vd_lookup(id): 'start_sector' : long(part_offset + lookup_raw_partn(partition)[0]['start_sector']), # extent size, in sectors 'nr_sectors' : nr_sectors, - # partition device this extent is on (useful to know for XenoUtil fns) + # partition device this extent is on (useful to know for xenctl.utils fns) 'part_device' : part_device, - # start sector within this partition (useful to know for XenoUtil fns) + # start sector within this partition (useful to know for xenctl.utils fns) 'part_start_sector' : part_offset, # type of this extent - handy to know 'type' : 'VD Extent' } diff --git a/tools/xenctl/setup.py b/tools/xenctl/setup.py new file mode 100644 index 0000000000..5dce290385 --- /dev/null +++ b/tools/xenctl/setup.py @@ -0,0 +1,8 @@ + +from distutils.core import setup, Extension + +setup(name = "xenctl", + version = "1.0", + packages = ["xenctl"], + package_dir = { "xenctl" : "lib" }, + ) -- 2.30.2